<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    img,
    video,
    canvas {
      width: 100px;
      height: 100px;
      /* display: block; */
      object-fit: cover;
    }
  </style>

<body>

  <input type="file">

  <script>
    /**
     * 绘制视频帧并返回帧数据和URL
     * @param {HTMLVideoElement} vdo - 视频元素
     * @returns {Promise<{ blob: Blob, url: string }>} 包含帧数据和URL的Promise
     */
    async function drawVideoFrame(vdo) {
      // 创建 Canvas 元素
      const canvas = document.createElement('canvas')
      // 获取 Canvas 上下文
      const context = canvas.getContext('2d')
      // 设置 Canvas 的宽高与视频宽高相同
      canvas.width = vdo.videoWidth
      canvas.height = vdo.videoHeight
      // 将视频帧绘制到 Canvas 上
      context.drawImage(vdo, 0, 0, canvas.width, canvas.height)
      // 将 Canvas 内容转换为 Blob
      const blob = await new Promise(reslove => canvas.toBlob(reslove))
      // 创建Blob的URL
      const url = URL.createObjectURL(blob)
      // 返回帧数据和URL
      return { blob, url }
    }

    /**
     * 捕获视频的某一帧
     * @param {File} vdoFile - 视频文件
     * @param {number} [time=0] - 帧时间
     * @returns {Promise<{ blob: Blob, url: string }>} 包含帧数据和URL的Promise
     */
    async function captureFrameFromVideo(videoFile, time = 10) {
      // 创建视频元素
      const videoElement = document.createElement('video')
      // 设置当前播放时间
      videoElement.currentTime = time;
      // 自动播放
      videoElement.autoplay = true;
      // 静音
      videoElement.muted = true;
      // 创建一个Promise，等待视频元素可以播放
      const videoCanPlay = new Promise(resolve => videoElement.oncanplay = resolve)
      // 设置视频元素的源为视频文件的URL
      videoElement.src = URL.createObjectURL(videoFile)
      // 等待视频元素可以播放
      await videoCanPlay
      // 绘制视频帧并返回帧数据和URL
      return await drawVideoFrame(videoElement)
    }

    /**
     * 创建图像预览元素并显示
     * @param {{ blob: Blob, url: string }} frame - 帧数据和URL
     */
    function createImagePreview(frame) {
      // 创建图像元素
      const img = document.createElement('img')
      // 设置图像元素的源为帧的URL
      img.src = frame.url
      // 将图像元素添加到页面的主体
      document.body.appendChild(img)
    }

    const inp = document.querySelector('input[type=file')

    // 当文件选择变化时触发
    inp.onchange = async e => {
      // 获取用户选择的文件
      const file = e.target.files[0]
      // 创建视频元素
      const videoElement = document.createElement('video')
      // 设置视频元素的源为视频文件的URL
      videoElement.src = URL.createObjectURL(file)
      // 创建一个Promise，等待视频元素可以播放然后获取时长
      await new Promise(resolve => videoElement.oncanplay = resolve)
      // 计算每帧的时间间隔
      const frameInterval = videoElement.duration / 10
      // 捕获视频的每一帧并创建预览
      for (let i = 0; i < 10; i++) {
        const frame = await captureFrameFromVideo(file, i * frameInterval)
        // 创建并显示图像预览
        createImagePreview(frame)
      }
    }
  </script>
</body>

</html>